package com.jinwei.qunguanjia.common.utils;

import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

import org.apache.commons.lang3.time.DateFormatUtils;

/**
 * 时间工具类
 * 
 * @author ruoyi
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYMMDD = "yyMMdd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前Date型日期
     * 
     * @return Date() 当前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     * 
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getDateTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String getDateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 增加 LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor)
    {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor)
    {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 获取当前时间到当天结束时间的毫秒数
     */
    public static Long getBetweenCurToEnd() {
        return getTimestampBetween(new Date(), getDayOfEnd());
    }

    /**
     * 获取两个时间的时间戳
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     */
    public static Long getTimestampBetween(Date startTime, Date endTime) {
        return endTime.getTime() - startTime.getTime();
    }

    /**
     * 获取当天的结束时间
     */
    public static Date getDayOfEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static String dateFormatToString(String date) throws ParseException {
        if (date == null) {
            return null;
        }
        return dateToString(DateUtils.stringToDate(date));
    }

    public static Date stringToDate(String date) throws ParseException {
        return new SimpleDateFormat(YYYY_MM_DD).parse(date);
    }

    public static Date stringToDateTime(String dateTime) throws ParseException {
        return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).parse(dateTime);
    }

    public static String dateToString(Date date) throws ParseException {
        return new SimpleDateFormat(YYYY_MM_DD).format(date);
    }

    /**
     *  获取指定月的毫秒数
     * @param number 传6代表6天后，-6代表6天前
     * @return 毫秒数
     */
    public static long getOffsetDay(Integer number){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + number);
        return calendar.getTimeInMillis();
    }

    /**
     *  获取指定月的毫秒数
     * @param number 传6代表6个月后，-6代表6个月前
     * @return 毫秒数
     */
    public static long getOffsetMonth(Integer number){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + number);
        return calendar.getTimeInMillis();
    }

    /**
     *  获取最近几个月的年月
     * @param number 传6代表最近6个月
     * @return 列表
     */
    public static List<String> getLatelyMonth(Integer number){
        List<String> resultList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        for (int i = 0; i < number; i++) {
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
            String month = (calendar.get(Calendar.MONTH ) + 1) < 10 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1) +"";
            resultList.add(calendar.get(Calendar.YEAR) + "-" + month);
        }
        Collections.reverse(resultList);
        return resultList;
    }

    /**
     *  获取最近几天的列表
     * @param number 传6代表最近6天
     * @return 列表
     */
    public static List<String> getLatelyDay(Integer number){
        List<String> resultList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("dd");
        for (int i = 1; i <= number; i++) {
            Date date = DateUtils.addDays(new Date(), -i);
            String formatDate = sdf.format(date);
            resultList.add(formatDate);
        }
        Collections.reverse(resultList);
        return resultList;
    }

    /**
     * 获取指定年月的自然天数列表
     * @param year 指定年份
     * @param month 指定月份
     * @return 列表
     */
    public static List<String> getMonthDays(Integer year, Integer month){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        int dateOfMonth = cal.getActualMaximum(Calendar.DATE);
        List<String> resultList = new ArrayList<>();
        for (int i = 1; i <= dateOfMonth; i++) {
            resultList.add(i < 10 ? "0" + i+"" : i+"");
        }
        return resultList;
    }

    public static String timeUtile(Date inTime) {
        // 拿到当前时间戳和发布时的时间戳，然后得出时间戳差
        Date curTime = new Date();
        long timeDiff = curTime.getTime() - inTime.getTime();
        //上面一行代码可以换成以下（兼容性的解决）

        // 单位换算
        long min = 60 * 1000;
        long hour = min * 60;
        long day = hour * 24;
        long week = day * 7;
        long month = week * 4;
        long year = month * 12;
        DecimalFormat df = new DecimalFormat("#");
        // 计算发布时间距离当前时间的周、天、时、分
        double exceedyear = Math.floor(timeDiff / year);
        double exceedmonth = Math.floor(timeDiff / month);
        double exceedWeek = Math.floor(timeDiff / week);
        double exceedDay = Math.floor(timeDiff / day);
        double exceedHour = Math.floor(timeDiff / hour);
        double exceedMin = Math.floor(timeDiff / min);


        // 最后判断时间差到底是属于哪个区间，然后return

        if (exceedyear < 100 && exceedyear > 0) {
            return df.format(exceedyear) + "年前";
        } else {
            if (exceedmonth < 12 && exceedmonth > 0) {
                return df.format(exceedmonth) + "月前";
            } else {
                if (exceedWeek < 4 && exceedWeek > 0) {
                    return df.format(exceedWeek) + "星期前";
                } else {
                    if (exceedDay < 7 && exceedDay > 0) {
                        return df.format(exceedDay) + "天前";
                    } else {
                        if (exceedHour < 24 && exceedHour > 0) {
                            return df.format(exceedHour) + "小时前";
                        } else {
                            if (df.format(exceedMin).equals("0")) {
                                return "刚刚";
                            } else {
                                return df.format(exceedMin) + "分钟前";
                            }

                        }
                    }
                }
            }
        }
    }


    public static void main(String [] args){
        System.out.println(getLatelyMonth(6));
        System.out.println(getLatelyDay(30));
        System.out.println(getMonthDays(2022, 10));
        System.out.println(getOffsetMonth(-6));
    }

}
